#include<stdio.h>
#define Size 10
#include<stdbool.h>
#include<string.h>



//初始化棋盘
void InitBoard(char (*Board)[Size])

{
    for(int i=0 ; i<Size;i++)         //将棋盘交叉点用-显示
    {
        for(int j=0;j<Size;j++)
        {
            Board[i][j]='-';     
        }
    }    
}
//显示棋盘
void PrintBoard(char (*Board)[Size])
{
    printf("   ");                   //用空格将第一列数字对其
    for(int i=0;i<Size;i++)         //显示row
    {
        printf("%d  ",i+1);
    }
    printf("\n");
    for(int i=0;i<Size;i++)
    {
        printf("%d  ",i+1);    //显示col
        for(int j=0;j<Size;j++)
        {
            printf("%c  ",Board[i][j]);
        }
        printf("\n");
        
    }
}
int main0()   //检测棋盘显示是否正常
{
    char Board[Size][Size]={'0'};
    InitBoard(Board);
    PrintBoard(Board);
}
bool IsValidPlace(int row,int col)
{
    if(row<0||row>=Size||col<0||col>=Size) //判断弈子是否越界
    {
        return false;
    }
    return true;
}
bool CheckIsWin(char (*Board)[Size],int row,int col,char player)
{
    
    int direction[4][2]=  //向量数组
    {
        {1,0},
        {1,1},
        {0,1},
        {-1,1}
    };
    for(int i=0;i<4;i++)
    {
        int count=1;
        int drow=row+direction[i][0];
        int dcol=col+direction[i][1];
        while(IsValidPlace(drow,dcol)&&Board[drow][dcol]==player)
        {
            count++;
            if(count==5)
                return true;
            drow=drow+direction[i][0];
            dcol=dcol+direction[i][1];
        }
        //反方向
        drow=row-direction[i][0];
        dcol=col-direction[i][1];
        while(IsValidPlace(drow,dcol)&&Board[drow][dcol]==player)
        {
            count++;
            if(count==5)
                return true;
            drow=drow-direction[i][0];
            dcol=dcol-direction[i][1];
        }
    }
    return false;
}
bool CheckIsCount(char (*Board)[Size],int row,int col,char player,int Num)
{
    int direction[4][2]=
    {
         {1,0},{1,1},{0,1},{-1,1}
    };
    for(int i=0;i<4;i++)
    {
        int count=1;
        int drow=row+direction[i][0];
        int dcol=col+direction[i][1];
        while(IsValidPlace(drow,dcol)&&Board[drow][dcol]==player)
        {
            count++;
            if(count==Num)
                return true;
            drow=drow+direction[i][0];
            dcol=dcol+direction[i][1];
        }
        //反方向
        drow=row-direction[i][0];
        dcol=col-direction[i][1];
        while(IsValidPlace(drow,dcol)&&Board[drow][dcol]==player)
        {
            count++;
            if(count==5)
                return true;
            drow=drow-direction[i][0];
            dcol=dcol-direction[i][1];
        }
    }
    return false;
}
bool MakeMove(char (*Board)[Size],int row,int col,char player)
{
    if(row<0||row>=Size||col<0||col>=Size)
    {
        printf("非法位置请重新输入！\n");
        return false;
    }
    if(Board[row][col]!='-')
    {
        printf("位置非空请重新输入！\n");
        return false;
    }
    Board [row][col]=player;
    return true;
}
bool CheckIsDrawn(char (*Board)[Size])
{
    for(int i=0;i<Size;i++)
    {
        for(int j=0;j<Size;j++)
        {
            if(Board[i][j]=='-')
            return false;
        }
    }
}
bool AIMakeMove(char (*Board)[Size],int PlayerRow,int PlayerCol,char player,char AI)
{
    //智能决策；决策算法；行为树
    //优先取胜策略
    for(int i=0;i<Size;i++)
    {
        for(int j=0;j<Size;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=AI;
                if(CheckIsWin(Board,i,j,AI)==true)
                {
                    return true;
                }
                Board[i][j]='-';
            }
        }
    }
    //阻止对手策略
        for(int i=0;i<Size;i++)
    {
        for(int j=0;j<Size;j++)
        {
            if(Board[i][j]=='-')
            {
                Board[i][j]=player;
                if(CheckIsWin(Board,i,j,player)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-';
            }
        }
    } 
    //阻止对手连成四个
    for(int i=0;i<Size;i++)
    {
        for(int j=0;j<Size;j++)
        {
            if(Board[i][j]=='-')
            {
               Board[i][j]=player;
                if(CheckIsCount(Board,i,j,player,4)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-'; 
            }
        }
    }
    //
    for(int i=0;i<Size;i++)
    {
        for(int j=0;j<Size;j++)
        {
            if(Board[i][j]=='-')
            {
               Board[i][j]=player;
                if(CheckIsCount(Board,i,j,player,3)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-'; 
            }
        }
    }

    for(int i=0;i<Size;i++)
    {
        for(int j=0;j<Size;j++)
        {
            if(Board[i][j]=='-')
            {
               Board[i][j]=player;
                if(CheckIsCount(Board,i,j,player,2)==true)
                {
                    Board[i][j]=AI;
                    return false;
                }
                Board[i][j]='-'; 
            }
        }
    }
}
void Single()
{
    int row,col;
    char Board[Size][Size]={0};
    InitBoard(Board);
    char player='X';

    while(1)
    {
        PrintBoard(Board);
        if(player=='X')
        {
            printf("请|%c|选手下棋",player);
            scanf("%d %d",&row,&col);
            if(MakeMove(Board,row-1,col-1,player)==false)
            {
                continue;
            }
        }
        else
        {
            printf("AI正在下棋。。。\n");
            if(AIMakeMove(Board,row-1,col-1,'X','O')==true)
            {
                PrintBoard(Board);
                printf("AI获胜!\n");
                break;
            }
        }
        
        if(CheckIsWin(Board,row-1,col-1,player)==true)
        {
            PrintBoard(Board);
            printf("恭喜|%c|选手获胜\n",player);
            break;
        }
        if(CheckIsDrawn(Board)==true)
        {
            PrintBoard(Board);
            printf("平局\n");
            break;
        }
        player=(player=='X')?'O':'X';
    }
}
void Double()
{
   int row,col;
    char Board[Size][Size]={0};
    InitBoard(Board);
    char player='X';

    while(1)
    {
        PrintBoard(Board);
        if(player=='X')
        {
            printf("请|%c|选手下棋",player);
            scanf("%d %d",&row,&col);
            if(MakeMove(Board,row-1,col-1,player)==false)
            {
                continue;
            }
        }
        else
        {
            printf("AI正在下棋。。。\n");
            if(AIMakeMove(Board,row-1,col-1,'X','O')==true)
            {
                PrintBoard(Board);
                printf("AI获胜!\n");
                break;
            }
        }
        
        if(CheckIsWin(Board,row-1,col-1,player)==true)
        {
            PrintBoard(Board);
            printf("恭喜|%c|选手获胜\n",player);
            break;
        }
        if(CheckIsDrawn(Board)==true)
        {
            PrintBoard(Board);
            printf("平局\n");
            break;
        }
        player=(player=='X')?'O':'X';
    }
}
int main1(int argc,char *argv[])
{
    if(argc<2)
    {
        printf("缺少启动参数！！！\n");
        return 0;
    }

    
    if(strcmp(argv[1],"1")==0)
    {
        Single();
    }
    else
    {
        Double();
    }

    return 0;

}
int main()
{

   int row,col;
    char Board[Size][Size]={0};
    InitBoard(Board);
    char player='X';

    while(1)
    {
        PrintBoard(Board);
        if(player=='X')
        {
            printf("请|%c|选手下棋",player);
            scanf("%d %d",&row,&col);
            if(MakeMove(Board,row-1,col-1,player)==false)
            {
                continue;
            }
        }
        else
        {
            printf("AI正在下棋。。。\n");
            if(AIMakeMove(Board,row-1,col-1,'X','O')==true)
            {
                PrintBoard(Board);
                printf("AI获胜!\n");
                break;
            }
        }
        
        if(CheckIsWin(Board,row-1,col-1,player)==true)
        {
            PrintBoard(Board);
            printf("恭喜|%c|选手获胜\n",player);
            break;
        }
        if(CheckIsDrawn(Board)==true)
        {
            PrintBoard(Board);
            printf("平局\n");
            break;
        }
        player=(player=='X')?'O':'X';
    }
    return 0;
}

